/*
 * @(#)DmsCheckoutExpiryTime.java
 *
 * Copyright (c) 2004 DCIVision Ltd
 * All rights reserved.
 *
 */

package com.dcivision.dms.core;

import java.net.InetAddress;
import java.sql.Connection;
import java.sql.Timestamp;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.dcivision.alert.bean.MtmUpdateAlertRecipient;
import com.dcivision.alert.bean.UpdateAlert;
import com.dcivision.alert.bean.UpdateAlertSystemLog;
import com.dcivision.alert.bean.UpdateAlertType;
import com.dcivision.alert.dao.MtmUpdateAlertRecipientDAObject;
import com.dcivision.alert.dao.UpdateAlertDAObject;
import com.dcivision.alert.dao.UpdateAlertSystemLogDAObject;
import com.dcivision.alert.dao.UpdateAlertTypeDAObject;
import com.dcivision.audit.AuditTrailConstant;
import com.dcivision.audit.core.AuditTrailManager;
import com.dcivision.dms.bean.DmsCheckoutHistory;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsVersion;
import com.dcivision.dms.dao.DmsCheckoutHistoryDAObject;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.dms.dao.DmsVersionDAObject;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.UserInfoFactory;
import com.dcivision.framework.Utility;
import com.dcivision.framework.notification.EmailDeliveryMessage;
import com.dcivision.framework.notification.NotificationWay;
import com.dcivision.framework.notification.NotificationWayFactory;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserRecordDAObject;
import com.dcivision.framework.bean.GenericAddress;

/**
 DmsCheckoutExpiryTime.java
 This class is checked in automatically action
 @author          jerry.zhou
 @company         DCIVision Limited
 @creation date   08/10/2004
 @version         $Revision: 1.13.2.2 $
 */
public class DmsCheckoutExpiryTime implements Job {

  public static final String REVISION = "$Revision: 1.13.2.2 $";

  protected Log log = LogFactory.getLog(this.getClass().getName());

  private String documentId = "";

  private Integer documentID;

  private String userId = "";

  private Integer userID;

  SessionContainer sessionContainer;

  Connection conn = null;

  public void execute(JobExecutionContext context) throws JobExecutionException {
    JobDataMap dataMap = context.getJobDetail().getJobDataMap();
    documentId = dataMap.getString("documentID");
    documentID = TextUtility.parseIntegerObj(documentId);
    userId = dataMap.getString("userID");
    userID = TextUtility.parseIntegerObj(userId);
    try {
      sessionContainer = new SessionContainer();
      conn = DataSourceFactory.getConnection();

      DmsVersionDAObject dmsVersionDAObject = new DmsVersionDAObject(sessionContainer, conn);
      DmsDocumentDAObject dmsDocumentDAO = new DmsDocumentDAObject(sessionContainer, conn);
      DmsDocument dmsDocument = (DmsDocument) dmsDocumentDAO.getDocumentByID(documentID, DmsVersion.AVAILABLE_STATUS);
      //        DmsVersion dmsVersion =(DmsVersion)dmsVersionDAObject.getObjectByID(TextUtility.parseIntegerObj(documentId));
      if (dmsDocument.getItemStatus().equals(DmsVersion.EXCLUSIVE_LOCK)) {
        this.unlockDocumentForNoUpdateCheckin(documentID);
        this.notifyBySystem(documentID, userID);
        log.info("send System Mesage");
        this.notifyByEmail(documentID, userID);
        log.info("send Email Mesage");
      }
    } catch (Exception e) {
      log.error(e, e);
    } finally {
      try {
        conn.close();
      } catch (Exception ignore) {
      } finally {
        conn = null;
      }
    }
  }

  public void unlockDocumentForNoUpdateCheckin(Integer documentID) {

    try {
      sessionContainer = new SessionContainer();
      //set user is administrator ,DAO method need updater id,creater id.
      UserRecord userRecord = new UserRecord();
      userRecord.setID(new Integer(0));
      sessionContainer.setUserRecord(userRecord);
      InetAddress address = InetAddress.getLocalHost();
      sessionContainer.setUserIPAddress(address.getHostAddress());
      conn = DataSourceFactory.getConnection();
      //update document info
      DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
      DmsDocument document = docRetrievalManager.getDocument(documentID);
      document.setItemStatus(DmsVersion.AVAILABLE_STATUS);
      document.setCheckoutID(null);

      /*
       * No-update-checkin will not update update_date or update_id
       * EIP-1438 07/01/11 LEE
       */
      DmsDocumentDAObject dmsDocumentDAO = new DmsDocumentDAObject(sessionContainer, conn);
      dmsDocumentDAO.documentSQLExecute("UPDATE", "ITEM_STATUS", DmsVersion.AVAILABLE_STATUS, document, false);
      dmsDocumentDAO.documentSQLExecute("UPDATE", "CHECKOUT_ID", null, document, false);
      dmsDocumentDAO = null;
      /*
       * EIP-1438 07/01/11 LEE
       DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
       DmsDocument newDocument = (DmsDocument)docOperationManager.updateDocument(document, false);
       docOperationManager.release();
       */

      DmsVersionDAObject dmsVersionDAO = new DmsVersionDAObject(sessionContainer, conn);
      DmsVersion dmsVersion = (DmsVersion) dmsVersionDAO.getTopVersionByDocumentID(documentID);
      dmsVersion.setItemStatus(DmsVersion.AVAILABLE_STATUS);
      dmsVersion = (DmsVersion) dmsVersionDAO.updateObject(dmsVersion);

      DmsCheckoutHistoryDAObject historyDAO = new DmsCheckoutHistoryDAObject(sessionContainer, conn);
      List currentLocker = historyDAO.getObjectByVersionAndCheckoutStatus(dmsVersion.getID(), DmsCheckoutHistory.CURRENT_RECORD);
      DmsCheckoutHistory checkoutHistory = (DmsCheckoutHistory) currentLocker.get(0);
      checkoutHistory.setCheckoutStatus(DmsCheckoutHistory.HISTORY_RECORD);
      checkoutHistory.setCheckinTime(new Timestamp(System.currentTimeMillis()));
      historyDAO.updateObject(checkoutHistory);
      historyDAO = null;
      // log down in audit trail
      if (sessionContainer.getUserRecordID() != null && sessionContainer.getSessionID() != null) {
        AuditTrailManager auditManager = new AuditTrailManager(sessionContainer, conn);
        auditManager.auditTrail(GlobalConstant.OBJECT_TYPE_DOCUMENT, document, AuditTrailConstant.ACCESS_TYPE_CHECK_IN, document
            .getVersionNumber());
        auditManager.release();
      }
      conn.commit();
      log.debug("Auto checkin successfull!");
    } catch (Exception e) {
      log.error(e, e);
      log.debug("Auto checkin false!");
    } finally {
      try {
        conn.close();
      } catch (Exception ignore) {
      } finally {
        conn = null;
      }
    }
  }

  public void notifyBySystem(Integer documentID, Integer userID) {
    try {
      sessionContainer = new SessionContainer();
      conn = DataSourceFactory.getConnection();

      UserRecordDAObject userRecordDAObject = new UserRecordDAObject(sessionContainer, conn);
      UserRecord userRecord = (UserRecord) userRecordDAObject.getObjectByID(userID);
      sessionContainer.setUserRecord(userRecord);

      UpdateAlertDAObject updateAlertDAO = new UpdateAlertDAObject(sessionContainer, conn);
      UpdateAlert updateAlert = new UpdateAlert();
      updateAlert.setObjectType(UpdateAlert.AUTOMATE_CHECKIN);
      //updateAlert.setObjectType(UpdateAlert.DOCUMENT_TYPE);
      updateAlert.setObjectID(documentID);
      updateAlert = (UpdateAlert) updateAlertDAO.insertObject(updateAlert);

      UpdateAlertTypeDAObject alertTypeDAO = new UpdateAlertTypeDAObject(sessionContainer, conn);
      //UpdateAlertType alertType = (UpdateAlertType)alertTypeDAO.getIDByTypeUpdateAlertID(eventType, updateAlert.getID());
      UpdateAlertType alertType = new UpdateAlertType();
      alertType.setUpdateAlertID(updateAlert.getID());
      //alertType.setActionType(UpdateAlert.INVITE_ACTION);
      alertType.setActionType(UpdateAlert.REMIND_ACTION);
      alertType.setNotifyWay(UpdateAlert.SYSTEM_NOTIFICATION);
      alertType = (UpdateAlertType) alertTypeDAO.insertObject(alertType);

      UpdateAlertSystemLogDAObject alertSystemLogDAO = new UpdateAlertSystemLogDAObject(sessionContainer, conn);
      UpdateAlertSystemLog alertSystemLog = new UpdateAlertSystemLog();
      alertSystemLog.setActionUserID(userID);
      alertSystemLog.setUpdateAlertTypeID(alertType.getID());
      alertSystemLog.setRecordStatus(GlobalConstant.STATUS_ACTIVE);
      alertSystemLog.setCreatorID(userID);
      alertSystemLog = (UpdateAlertSystemLog) alertSystemLogDAO.insertObject(alertSystemLog);

      MtmUpdateAlertRecipientDAObject alertRecipientDAO = new MtmUpdateAlertRecipientDAObject(sessionContainer, conn);
      MtmUpdateAlertRecipient recipient = new MtmUpdateAlertRecipient();
      recipient.setUpdateAlertID(updateAlert.getID());
      recipient.setRecipientType(UpdateAlert.USER_RECIPIENT);
      recipient.setRecipientID(userID);
      recipient.setUpdateAlertTypeID(alertType.getID());
      recipient.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
      recipient = (MtmUpdateAlertRecipient) alertRecipientDAO.insertObject(recipient);

      updateAlertDAO = null;
      alertTypeDAO = null;
      alertSystemLogDAO = null;
      alertRecipientDAO = null;

      conn.commit();
    } catch (Exception e) {
      log.error(e, e);
    } finally {
      try {
        conn.close();
      } catch (Exception ignore) {
      } finally {
        conn = null;
      }
    }
  }

  public void notifyByEmail(Integer documentID, Integer userID) {
    NotificationWay notifyWay = NotificationWayFactory.getNotificationInstance(NotificationWay.EMAIL_NOTIFICATION_INSTANCE);
    try {
      sessionContainer = new SessionContainer();
      conn = DataSourceFactory.getConnection();
      UserRecordDAObject userRecordDAObject = new UserRecordDAObject(sessionContainer, conn);
      UserRecord userRecord = (UserRecord) userRecordDAObject.getObjectByID(userID);
      sessionContainer.setUserRecord(userRecord);
      String curUserEmail = UserInfoFactory.getUserEmailAddress(sessionContainer.getUserRecordID());
      if (!Utility.isEmpty(curUserEmail)) {
        EmailDeliveryMessage mesg = new EmailDeliveryMessage();
        StringBuffer content = new StringBuffer();
        DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
        DmsDocument document = docRetrievalManager.getDocument(documentID);
        content.append("Dear " + userRecord.getFullName() + ",\n\n");
        content.append("Auto CheckIn Document Name:" + document.getDocumentName() + "\n");
        content.append("Auto Check Date:" + document.getUpdateDate() + "\n");
        content.append("\n\n");
        content.append("Please attention this document already auto checkin.\n\n");
        String smtpAdminAddress = SystemParameterFactory.getSystemParameter(SystemParameterConstant.SMTP_ADMIN_ADDRESS);
        String smtpAdminName = SystemParameterFactory.getSystemParameter(SystemParameterConstant.SMTP_ADMIN_NAME);
        mesg.setSender(new GenericAddress(smtpAdminAddress, smtpAdminName, "UTF-8"));
        mesg.addToRecipient(new GenericAddress(curUserEmail, curUserEmail, "UTF-8"));
        mesg.setSubject("Auto Checkin System Notification");
        mesg.setMailContent(content.toString());
        notifyWay.addDeliveryMessage(mesg);
        notifyWay.send();
      }
    } catch (Exception e) {
      log.error("error in add recipient");
    } finally {
      try {
        conn.close();
      } catch (Exception dber) {
      } finally {
        conn = null;
      }
    }
  }
}
